//
// Created by 叶璨铭 on 2022/5/17.
//
#pragma once
#include "utils/macro.h"
#include <algorithm>
#include <cstring>
#include <ostream>
#include <string>
#define LabelBeginFor(labelName) "<" << labelName << ">"
#define LabelEndFor(labelName) "</" << labelName << ">"
#define _DefSingle(struct_name, label_name)                                                             \
    struct xml_element_##struct_name {                                                                  \
        std::string m_##struct_name;                                                                    \
        friend std::ostream &operator<<(std::ostream &os, const xml_element_##struct_name &obj) {       \
            return os << LabelBeginFor(#label_name) << obj.m_##struct_name << LabelEndFor(#label_name); \
        }
#define DefSingle(StructName) _DefSingle(StructName, StructName)
DefSingle(folder);
DefSingle(filename);
DefSingle(database);
#define StructDef_SEP(NAME, I, REC, RES) REC RES
#define StructDef_DeclareField(NAME, X, I) xml_element_##X m_##X;
#define DefComposite(StructName, ...)                                                            \
    struct StructName {                                                                          \
        static constexpr const char labelName[] = #StructName;                                   \
        P99_FOR(VOID, P99_NARG(__VA_ARGS__), StructDef_SEP, StructDef_DeclareField, __VA_ARGS__); \
    }

DefComposite(VocAnnotationXml, folder, fileName);
//struct VocAnnotationXml {
//    static constexpr const char *labelName = "annotation";
//    friend std::ostream &operator<<(std::ostream &os, const VocAnnotationXml &vocAnnotationXml) {
//        return os << LabelBeginFor(labelName) << LabelEndFor(labelName);
//    }
//};
